/*
* Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "utils.h"
#include <cctype>
#include <cstddef>
#include <string>

static uint8_t hex_to_byte(char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    if (c >= 'a' && c <= 'f') {
        return c - 'a' + 10;
    }
    if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    }
    return UINT8_MAX;
}

std::optional<std::vector<uint8_t>> parse_bin_text(std::string_view bin_text) {
    std::vector<uint8_t> data;
    for (size_t i = 0; i < bin_text.size(); ++i) {
        if (bin_text[i] == ' ') {
            continue;
        }
        if (i + 1 >= bin_text.size()) {
            continue;
        }
        uint8_t high = hex_to_byte(bin_text[i]);
        uint8_t low = hex_to_byte(bin_text[i + 1]);
        if (high == UINT8_MAX || low == UINT8_MAX) {
            return std::nullopt;
        }
        
        data.push_back(high << 4 | low);
        ++i;
    }
    return data;
}

std::string compact_ron_text(std::string_view ron_text) {
    std::string result;

    bool in_string = false;
    for (size_t i = 0; i < ron_text.size(); ++i) {
        if (ron_text[i] == '"' && i > 0 && ron_text[i - 1] != '\\') {
            in_string = !in_string;
        }

        if (isspace(ron_text[i]) && !in_string) {
            continue;
        }

        if (ron_text[i] == ',' && !in_string) {
            size_t j = i;
            while (i + 1 < ron_text.size() && isspace(ron_text[i + 1])) {
                ++i;
            }

            if (i + 1 < ron_text.size() && ((ron_text[i + 1] == ')') || (ron_text[i + 1] == ']'))) {
                continue;
            }

            result.push_back(',');
            continue;
        }

        result.push_back(ron_text[i]);
    }
    return result;
}
